package com.ww.learn.coroutine

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ClosedReceiveChannelException
import kotlinx.coroutines.delay
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.random.Random

@OptIn(ExperimentalCoroutinesApi::class)
fun main() = runBlocking {
    // 创建一个带缓冲的通道，容量为5
    val channel = Channel<Int>(capacity = 5)

    // 启动3个生产者协程
    val producerCount = 3
    val producers = List(producerCount) { producerId ->
        launch(Dispatchers.Default) {
            // 每生产者生成5个数据
            repeat(5) { itemId ->
                val value = producerId * 100 + itemId
                // 模拟生产数据的耗时操作
                delay(Random.nextLong(100, 300))
                channel.send(value)
                println("生产者 $producerId 发送了：$value [缓冲区为空：${channel.isEmpty}]")
            }
            println("生产者 $producerId 完成生产")
        }
    }

    // 启动2个消费协程
    val consumerCount = 2
    val consumers = List(consumerCount) { consumerId ->
        launch(Dispatchers.Default) {
            try {
                // 循环接收数据直到通道关闭
                while (true) {
                    val value = channel.receive()
                    // 模拟处理数据的耗时操作
                    delay(Random.nextLong(200, 400))
                    println("消费者 $consumerId 处理了：$value [缓冲区为空：${channel.isEmpty}]")
                }
            } catch (e: ClosedReceiveChannelException) {
                // 通道关闭时退出循环
                println("消费者 $consumerId 发现通道已关闭，退出")
            }
        }
    }

    // 等待所有生产者完成
    producers.joinAll()
    // 所有生产者完成后关闭通道
    channel.close()
    println("所有生产者已完成，通道已关闭")

    // 等待所有消费者处理完剩余数据并退出
    consumers.joinAll()
    println("所有消费者已完成，程序结束")
}